﻿using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using Blazor.Core;
using Blazor.Localization;
using Blazor.ViewModels.DeviceList;
using Blazor.Views.DeviceList.Modals;
using ReactiveUI;

namespace Blazor.Views.DeviceList;

public partial class DeviceList : SoraniComponentBase<DeviceListViewModel>
{
    private readonly ILogger _logger;

    public DeviceList(DeviceListViewModel viewModel, ILogger<DeviceList> logger)
    {
        ViewModel = viewModel;
        _logger = logger;
    }

    protected override void BindWithViewModel(DeviceListViewModel viewModel, CompositeDisposable disposable)
    {
        viewModel.DeviceEntryInteraction.RegisterHandler(DeviceEntryInteractionHandler).DisposeWith(disposable);
        viewModel.ConfirmDeleteInteraction.RegisterHandler(ConfirmDeleteInteractionHandler).DisposeWith(disposable);
    }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();

        if (ViewModel is not null)
        {
            await ViewModel.InitAsync();
        }
    }

    private async Task NewClickHandler()
    {
        if (ViewModel is null)
        {
            return;
        }

        await ViewModel.New.Execute();
    }

    private async Task ChangeClickHandler(DeviceListViewModel.DeviceEntry item)
    {
        if (ViewModel is null)
        {
            return;
        }

        await ViewModel.Change.Execute(item.Id);
    }

    private async Task DeleteClickHandler(DeviceListViewModel.DeviceEntry item)
    {
        if (ViewModel is null)
        {
            return;
        }

        await ViewModel.Delete.Execute(item.Id);
    }

    private async Task DeviceEntryInteractionHandler(IInteractionContext<DeviceListViewModel.DeviceEntry?, DeviceListViewModel.DeviceEntry?> interactionContext)
    {
        var option = interactionContext.Input is {} entry
            ? DeviceEntryEditorOption.ChangeAll(entry.Id.ToString(), entry.Description)
            : DeviceEntryEditorOption.New();

        var result = await OpenCustomModal<DeviceEntryEditorModal, DeviceEntryEditorOption, DeviceEntryEditorResult?>(option);

        if (result is null)
        {
            interactionContext.SetOutput(null);
        }
        else if (Guid.TryParse(result.Id, out var id))
        {
            interactionContext.SetOutput(DeviceListViewModel.DeviceEntry.New(id, result.Description));
        }
        else
        {
            interactionContext.SetOutput(null);
        }
    }

    private async Task ConfirmDeleteInteractionHandler(IInteractionContext<Unit, bool> interactionContext)
    {
        var confirmed = await WhenConfirm(CommonLoc[CommonLocalization.DeleteTip]);
        interactionContext.SetOutput(confirmed);
    }
}